package com.atguigu.bookcity.controller;


import com.atguigu.bookcity.entity.BookPurchaseApply;
import com.atguigu.bookcity.entity.vo.BookPurchaseVo;
import com.atguigu.bookcity.exception.BookCityException;
import com.atguigu.bookcity.service.BookPurchaseApplyService;
import com.atguigu.bookcity.status.ApplyEnum;
import com.atguigu.bookcity.vo.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zsc
 * @since 2021-05-31
 */
@Slf4j
@CrossOrigin
@Api(tags = "购书申请接口")
@RestController
@RequestMapping("/bookcity/bookPurchaseApply")
public class BookPurchaseApplyController {
    @Resource
    private BookPurchaseApplyService bookPurchaseApplyService;

    @Resource
    private TaskService taskService;

    @Resource
    private RuntimeService runtimeService;


    /**
     * 提交购书申请
     */
    @ApiOperation("购书申请")
    @PostMapping("/submitApply")
    public CommonResult addStockApply(@RequestBody BookPurchaseVo bookPurchaseVo) {
        boolean flag = bookPurchaseApplyService.addApply(bookPurchaseVo);
        if (flag)
            return CommonResult.ok();
        return CommonResult.error();
    }


    /**
     * 获取我的申请
     *
     * @param userId u
     */
    @ApiOperation("获取我的申请")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", required = true)
    })
    @PostMapping("/getMyApplies")
    public CommonResult getMyApplies(@RequestParam("userId") String userId) {
        List<BookPurchaseApply> bookPurchaseApplies =
                bookPurchaseApplyService.getByUserId(userId);
        //将bookPurchaseApplies回传
        return CommonResult.ok().data("bookPurchaseApplies", bookPurchaseApplies);
    }


    /**
     * 数量大于10000经理完成审批
     */
    @ApiOperation("完成审批")
    @PostMapping("/completeTask")
    @RequiresRoles(value = {"manager", "financial"}, logical = Logical.OR)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "评论"),
            @ApiImplicitParam(name = "isPass", value = "是否同意", required = true, dataType = "boolean"),
            @ApiImplicitParam(name = "applyId", value = "购书申请id", required = true, dataType = "String")
    })
    public CommonResult complete(@RequestParam(value = "content", required = false) String content,
                                 @RequestParam("isPass") boolean isPass,
                                 @RequestParam("applyId") String applyId) {
        try {
            Map<String, Object> variables = new HashMap<>();
            variables.put("isPass", isPass);
            //通过businessKey获取taskId和processInstanceId
            Task task =
                    taskService
                            .createTaskQuery()
                            .processInstanceBusinessKey(applyId)
                            .singleResult();
            String taskId = task.getId();
            String processInstanceId = task.getProcessInstanceId();

            //添加评论
            if (StringUtils.isEmpty(content) && isPass)
                content = "同意";
            if (StringUtils.isEmpty(content) && !isPass)
                content = "不同意";
            Authentication.setAuthenticatedUserId(task.getAssignee());
            taskService.addComment(taskId, processInstanceId, content);

            //执行任务
            taskService.complete(taskId, variables);
            log.info("审批完成 经理或财务的id：" + task.getAssignee());


            //判断申请是否通过（若流程实例为空则说明结束）
            BookPurchaseApply bookPurchaseApply = bookPurchaseApplyService.getById(applyId);
            if (isPass) {
                ProcessInstance processInstance =
                        runtimeService.createProcessInstanceQuery()
                                .processInstanceBusinessKey(applyId)
                                .singleResult();
                log.info("all finish processInstance:" + processInstanceId);
                if (processInstance == null) {
                    bookPurchaseApply.setStatus(ApplyEnum.APPLY_SUCCESS.getMessage());
                    bookPurchaseApplyService.updateById(bookPurchaseApply);
                    log.info("%%%%%%%%申请成功！:" + bookPurchaseApply.getStatus());
                    log.info("%%%%%%%%%审批成功！");
                }
            } else {
                bookPurchaseApply.setStatus(ApplyEnum.APPLY_FAILED.getMessage());
                bookPurchaseApplyService.updateById(bookPurchaseApply);
                log.info("%%%%%%%%%申请失败！:" + bookPurchaseApply.getStatus());
            }
            return CommonResult.ok();
        } catch (Exception e) {
            throw new BookCityException(201, "");
        }

    }


    /**
     * 调整申请
     */
    @ApiOperation(value = "申请者调整申请", notes = "如果重新申请bookPurchaseApplyVo需要传（重新传时回显修改），不重新申请则applyId需要传")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reApply", value = "是否同意", required = true, dataType = "boolean")
    })
    @PostMapping("/modifyBookApply")
    public CommonResult modifyApply(@RequestBody(required = false) BookPurchaseVo bookPurchaseVo,
                                    @RequestParam("reApply") boolean reApply,
                                    @RequestParam("isPass") boolean isPass) {

        //Rest rest = new Rest();

        //重新申请
        if (reApply) {
            //修改申请
            BookPurchaseApply bookPurchaseApply = new BookPurchaseApply();
            BeanUtils.copyProperties(bookPurchaseVo, bookPurchaseApply);
            bookPurchaseApply.setStatus(ApplyEnum.PENDING.getMessage());
            bookPurchaseApplyService.updateById(bookPurchaseApply);
            //再次申请
            Map<String, Object> variables = new HashMap<>();
            variables.put("bookPurchaseApply", bookPurchaseApply);
            //
            variables.put("isPass", isPass);
            String taskId =
                    taskService.createTaskQuery()
                            .processInstanceBusinessKey(
                                    bookPurchaseApply.getApplyId()
                            )
                            .singleResult()
                            .getId();
            taskService.complete(taskId, variables);
            log.info("重新申请成功");
            return CommonResult.ok();
        }
        //取消申请
        String processInstanceId
                = taskService
                .createTaskQuery()
                .processInstanceBusinessKey(bookPurchaseVo.getApplyId())
                .singleResult().getProcessInstanceId();
        //删除实例
        runtimeService.deleteProcessInstance(processInstanceId, null);
        log.info("取消申请成功");
        return CommonResult.ok();

    }

    /**
     * 我的待审批的任务
     */
    @ApiOperation("审批人待审批的任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "page", value = "当前页面", required = true, dataType = "String"),
            @ApiImplicitParam(name = "limit", value = "每页条数", required = true, dataType = "String")
    })
    @GetMapping("/assigneeTasks")
    public CommonResult getAssigneeTasks(@RequestParam("userId") String userId,
                                         @RequestParam("page") Integer page,
                                         @RequestParam("limit") Integer limit) {
        List<BookPurchaseApply> myTasks =
                bookPurchaseApplyService.getMyTasks(
                        userId, page, limit
                );
        return CommonResult.ok().data("myTasks", myTasks);
    }

    /**
     * 查询我的可办任务
     */
    @ApiOperation("查询审批人的可办任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户Id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "page", value = "当前页面", required = true, dataType = "String"),
            @ApiImplicitParam(name = "limit", value = "每页条数", required = true, dataType = "String")
    })
    @GetMapping("/candidate/tasks")
    public CommonResult getCandidateTasks(@RequestParam("userId") String userId,
                                          @RequestParam("page") Integer page,
                                          @RequestParam("limit") Integer limit) {
        List<BookPurchaseApply> myCandidateTasks =
                bookPurchaseApplyService
                        .getCandidateTasks(
                                userId, page, limit
                        );
        return CommonResult.ok().data("myCandidateTasks", myCandidateTasks);
    }

    /**
     * 拾取任务
     */
    @ApiOperation("拾取任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "applyId", value = "购书申请Id", required = true, dataType = "String")
    })
    @PostMapping("/pickUpTask")
    public CommonResult pickUpTask(@RequestParam("userId") String userId,
                                   @RequestParam("applyId") String applyId) {
        try {
            String taskId =
                    taskService.createTaskQuery()
                            .processInstanceBusinessKey(applyId)
                            .singleResult()
                            .getId();
            taskService.claim(taskId, userId);
            log.info("拾取成功");
            return CommonResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.error();
        }

    }

    /**
     * 放弃任务
     */
    @ApiOperation("放弃任务")
    @PostMapping("/discardPickUpTask")
    public CommonResult discardPickUpTask(@RequestParam("applyId") String applyId) {
        try {
            String taskId =
                    taskService.createTaskQuery()
                            .processInstanceBusinessKey(applyId)
                            .singleResult()
                            .getId();
            taskService.unclaim(taskId);
            return CommonResult.ok();
        } catch (Exception e) {
            e.printStackTrace();
            log.info("放弃任务失败");
            return CommonResult.error();

        }

    }
}

